namespace Bowlus.Common.Communications
{
    using System;
    using System.ServiceModel;
    using System.Threading;

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    internal sealed class CommunicationService : ICommunicationService
    {
        private static readonly object SyncLock = new object();

        private readonly Action<BowlusMessage> messageHandler;

        private static volatile CommunicationService instance;

        private CommunicationService(Action<BowlusMessage> handler)
        {
            this.messageHandler = handler;
        }

        // TODO: We won't need this Singlton method.
        // See: use 'new ServiceHost(Type)' instead of 'new ServiceHost(Instance)'
        // We have specified service object initiation bebavior in:
        //       [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
        // ServichHost will control instance bahavior, and we should give up control on how ServiceHost initiate the service object.
        public static CommunicationService Instance(Action<BowlusMessage> handler)
        {
            if (instance == null)
            {
                lock (SyncLock)
                {
                    if (instance == null)
                    {
                        instance = new CommunicationService(handler);
                    }
                }
            }

            return instance;
        }

        // TODO: Look at the threading implementation here once more
        public void HandleMessage(BowlusMessage msg)
        {
            var thread = new Thread(() => this.messageHandler(msg));
            thread.Start();
        }
    }
}